﻿// -----------------------------------------------------------------------
// <copyright company="Christoph van der Fecht - VDsoft">
// Copyright (C) Christoph van der Fecht - VDsoft - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited,
// unless it is communicated and authorized by the copyright owner.
// </copyright>
// -----------------------------------------------------------------------

namespace SeriesManager.ViewModel
{
	using System;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.Linq;
	using System.Text;
	using System.Threading.Tasks;
	using GalaSoft.MvvmLight;
	using GalaSoft.MvvmLight.Command;
	using SeriesManager.Model;
	using GalaSoft.MvvmLight.Messaging;
using TVDB.Model;
using System.Windows;

	/// <summary>
	/// View model for the main view.
	/// </summary>
	public class MainViewModel : ViewModelBase
	{
		/// <summary>
		/// Name of the <see cref="SelectedMirror"/> property.
		/// </summary>
		private const string SelectedMirrorName = "SelectedMirror";

		/// <summary>
		/// Name of the <see cref="SeriesBanner"/> property.
		/// </summary>
		private const string SeriesBannerName = "SeriesBanner";

		/// <summary>
		/// Name of the <see cref="Title"/> property.
		/// </summary>
		private const string TitleName = "Title";

		/// <summary>
		/// All details of the selected series.
		/// </summary>
		private SeriesDetails selectedDetails = null;

		/// <summary>
		/// Mirror that was selected.
		/// </summary>
		private Mirror selectedMirror = null;

		/// <summary>
		/// Banner image of the selected series.
		/// </summary>
		private string seriesBanner = string.Empty;

		/// <summary>
		/// Title of the main window.
		/// </summary>
		private string title = "Series Manager";

		#region private commands

		/// <summary>
		/// Command to show the search dialog.
		/// </summary>
		private RelayCommand showSearchDialogCommand = null;

		/// <summary>
		/// Command to close the window.
		/// </summary>
		private RelayCommand<Window> closeWindowCommand = null;

		/// <summary>
		/// Command to show the options dialog.
		/// </summary>
		private RelayCommand showOptionsDialogCommand = null;

		/// <summary>
		/// Command to show the about dialog.
		/// </summary>
		private RelayCommand showAboutDialogCommand = null;

		#endregion

		/// <summary>
		/// Initializes a new instance of the <see cref="MainViewModel"/> class.
		/// </summary>
		public MainViewModel()
		{
			if (this.IsInDesignMode)
			{
				Mirror mirror0 = new Mirror()
				{
					Address = "http://thetvdb.com",
					ContainsBannerFile = true,
					ContainsZipFile = true,
					ContainsXmlFile = false
				};

				this.SeriesBanner = "http://www.thetvdb.com/banners/text/83462.jpg";
				this.SelectedMirror = mirror0;
				this.Title = "Series Manager - Castle";
			}
			else
			{
				// real...
				Messenger.Default.Register<SeriesDetails>(this, ViewModelLocator.SearchSeriesToken, this.ReceivedSeries);
				Messenger.Default.Register<Mirror>(this, ViewModelLocator.SearchSeriesToken, this.ReceiveMirror);
			}
		}

		/// <summary>
		/// Gets or sets the Mirror that was selected.
		/// </summary>
		public Mirror SelectedMirror
		{
			get
			{
				return this.selectedMirror;
			}

			set
			{
				if (value == this.selectedMirror)
				{
					return;
				}

				this.selectedMirror = value;
				this.RaisePropertyChanged(SelectedMirrorName);
			}
		}

		/// <summary>
		/// Gets or sets the Banner image of the selected series.
		/// </summary>
		public string SeriesBanner
		{
			get
			{
				return this.seriesBanner;
			}

			set
			{
				if (value == this.seriesBanner)
				{
					return;
				}

				this.seriesBanner = value;
				this.RaisePropertyChanged(SeriesBannerName);
			}
		}

		/// <summary>
		/// Gets or sets the title of the main window.
		/// </summary>
		public string Title
		{
			get
			{
				return this.title;
			}

			set
			{
				if (value == this.title)
				{
					return;
				}

				this.title = value;
				this.RaisePropertyChanged(TitleName);
			}
		}

		#region public commands

		/// <summary>
		/// Gets the command to search for a series.
		/// </summary>
		public RelayCommand ShowSearchDialogCommand
		{
			get
			{
				if (this.showSearchDialogCommand == null)
				{
					this.showSearchDialogCommand = new RelayCommand(this.ShowSearchDialog);
				}

				return this.showSearchDialogCommand;
			}
		}

		/// <summary>
		/// Gets the command to close the provided window.
		/// </summary>
		public RelayCommand<Window> CloseWindowCommand
		{
			get
			{
				if (this.closeWindowCommand == null)
				{
					this.closeWindowCommand = new RelayCommand<Window>(this.CloseWindow);
				}

				return this.closeWindowCommand;
			}
		}

		/// <summary>
		/// Gets the command to show the <see cref="OptionsDialog"/>.
		/// </summary>
		public RelayCommand ShowOptionsDialogCommand
		{
			get
			{
				if (this.showOptionsDialogCommand == null)
				{
					this.showOptionsDialogCommand = new RelayCommand(this.ShowOptionsDialog);
				}

				return this.showOptionsDialogCommand;
			}
		}

		/// <summary>
		/// Gets the command to show the <see cref="AboutDialog"/>.
		/// </summary>
		public RelayCommand ShowAboutDialogCommand
		{
			get
			{
				if (this.showAboutDialogCommand == null)
				{
					this.showAboutDialogCommand = new RelayCommand(this.ShowAboutDialog);
				}

				return this.showAboutDialogCommand;
			}
		}

		#endregion

		/// <summary>
		/// Shows the dialog to search for a series.
		/// </summary>
		private void ShowSearchDialog()
		{
			SearchSeries dialog = new SearchSeries();
			dialog.ShowDialog();
		}

		/// <summary>
		/// Sets the received series.
		/// </summary>
		/// <param name="received">Series to set.</param>
		private void ReceivedSeries(SeriesDetails received)
		{
			if (received == null)
			{
				return;
			}

			this.selectedDetails = received;

			if (this.SelectedMirror != null)
			{
				this.SeriesBanner = string.Format("{0}/banners/{1}", this.SelectedMirror.Address, this.selectedDetails.Series.Banner);
			}

			this.UpdateTitle();
			this.ForwardSeriesDetails();
		}

		/// <summary>
		/// Forwards the details of the selected series.
		/// </summary>
		private void ForwardSeriesDetails()
		{
			Model.Series forwardSeries = (Model.Series)this.selectedDetails.Series;

			// convert banners
			List<Model.Banner> forwardBanners = new List<Model.Banner>();

			foreach (var current in this.selectedDetails.Banners)
			{
				forwardBanners.Add((Model.Banner)current);
			}

			// convert actors.
			List<Model.Actor> forwardActors = new List<Model.Actor>();
			foreach (var current in selectedDetails.Actors)
			{
				forwardActors.Add((Model.Actor)current);
			}

			Messenger.Default.Send<Model.Series>(forwardSeries, ViewModelLocator.SeriesDetailsToken);
			Messenger.Default.Send<List<Model.Banner>>(forwardBanners, ViewModelLocator.SeriesBannerToken);
			Messenger.Default.Send<List<Model.Actor>>(forwardActors, ViewModelLocator.SeriesActorToken);
		}

		/// <summary>
		/// Receivs the mirror that was selected by the search dialog.
		/// </summary>
		/// <param name="received">Mirror to use.</param>
		private void ReceiveMirror(Mirror received)
		{
			if (received == null)
			{
				return;
			}

			this.SelectedMirror = received;
		}

		/// <summary>
		/// Updates the title of the main window.
		/// </summary>
		private void UpdateTitle()
		{
			this.Title = string.Concat("Series Manager - ", this.selectedDetails.Series.Name);
		}

		/// <summary>
		/// Closes the provided window.
		/// </summary>
		/// <param name="window">Instance of the window to close.</param>
		private void CloseWindow(Window window)
		{
			if (window != null)
			{
				window.Close();
			}
		}

		/// <summary>
		/// Shows the <see cref="OptionsDialog"/>.
		/// </summary>
		private void ShowOptionsDialog()
		{
			OptionsView dialog = new OptionsView();
			dialog.ShowDialog();
		}

		/// <summary>
		/// Shows the <see cref="AboutDialog"/>.
		/// </summary>
		private void ShowAboutDialog()
		{
			AboutDialog dialog = new AboutDialog();
			dialog.ShowDialog();
		}
	}
}
